<?php
namespace Go\Controller;
use Pingpp;
use Pingpp\Util\Util;

class PaymentController extends BaseController {
	
	private $db;
	private $Cartlist;
	private $path;
	private $model=null;
	public function _initialize(){
		parent::_initialize();
		$this->Cartlist = cookie('Cartlist');
		$this->path = dirname(__DIR__).'/Util/pingpp';
		$this->model = new \Think\Model();
	}
	
	private function config(){
		require $this->path.'/init.php';
		//api_key、app_id 请从 [Dashboard](https://dashboard.pingxx.com) 获取
		$api_key = 'sk_live_f1OCW9vfrzf9CCajb9PG8aPO';
		$app_id = 'app_KOKurHerfT84Hanv';
		$input_data = $_POST;
		if (empty($input_data['channel']) || empty($input_data['amount'])) {
			$this->ajaxReturn(array('status' => 0,'msg' => 'channel or amount is empty'));
		}
		$channel = strtolower($input_data['channel']);
		$amount = $input_data['amount'];
		$orderNo = substr(md5(time()), 0, 12);
		$open_id = $input_data['code'];
		//支付宝，JD支付需要设置 设置请求签名密钥，密钥对需要你自己用 openssl 工具生成，把公钥填写到 https://dashboard.pingxx.com
		Pingpp\Pingpp::setPrivateKeyPath($this->path . '/pay/rsa_private_key.pem');
		/**
		 * $extra 在使用某些渠道的时候，需要填入相应的参数，其它渠道则是 array()。
		 * 以下 channel 仅为部分示例，未列出的 channel 请查看文档 https://pingxx.com/document/api#api-c-new
		*/
		$extra = array();
		switch ($channel) {
			case 'alipay_wap':
				$extra = array(
				'success_url' => 'http://example.com/success',
				'cancel_url' => 'http://example.com/cancel',
				'pay_type' => '支付宝');
				break;
			case 'bfb_wap':
				$extra = array(
				'result_url' => 'http://example.com/result',
				'bfb_login' => true,
				'pay_type' => '百度钱包'
						);
						break;
			case 'upacp_wap':
				$extra = array(
				'result_url' => 'http://example.com/result',
				'pay_type' => '银联'
						);
						break;
			case 'wx_pub':
				$extra = array(
				'open_id' => $open_id,
				'pay_type' => '微信支付',
				);
				break;
			case 'wx_pub_qr':
				$extra = array(
				'product_id' => 'Productid',
				'pay_type' => '微信支付',
				);
				break;
			case 'yeepay_wap':
				$extra = array(
				'product_category' => '1',
				'identity_id'=> 'your identity_id',
				'identity_type' => 1,
				'terminal_type' => 1,
				'terminal_id'=>'your terminal_id',
				'user_ua'=>'your user_ua',
				'result_url'=>'http://example.com/result',
				'pay_type' => '易宝支付'
						);
						break;
			case 'jdpay_wap':
				$extra = array(
				'success_url' => 'http://example.com/success',
				'fail_url'=> 'http://example.com/fail',
				'token' => 'dsafadsfasdfadsjuyhfnhujkijunhaf',
				'pay_type' => '京东支付'
						);
						break;
		}
	
		return array(
				'api_key' => $api_key,
				'app_id' => $app_id,
				'channel' => $channel,
				'amount' => $amount,
				'orderNo' => $orderNo,
				'openId' => $open_id,
				'extra' => $extra
		);
	}
	
	public function pay(){
		if (!IS_AJAX) $this->ajaxReturn(array('status' => 0,'msg' => '非法操作'));
		if (!$this->userinfo){
			$this->ajaxReturn(array('status' => 0,'msg' => '请登录用户'));
		}
		$Mcartlist=json_decode(stripslashes($this->Cartlist),true);
		$this->model->startTrans();
		$shopids='';
		if(is_array($Mcartlist)){
			foreach($Mcartlist as $key => $val){
				$shopids.=intval($key).',';
			}
			$shopids=str_replace(',0','',$shopids);
			$shopids=trim($shopids,',');
		}
		$shoplist=array();
		if($shopids!=NULL){
			$shoplist=$this->model->query("SELECT * FROM `__PREFIX__shoplist` where `id` in($shopids)");
	
			$_temp = array();
			foreach ($shoplist as $key => $value){
				$_temp[$value['id']] = $value;
			}
			$shoplist = $_temp;
				
		}else{
			$this->ajaxReturn(array('status' => 0,'msg' => '购物车里没有商品'));
		}
		if(count($shoplist)>=1){
			$scookies_arr = array();
			$scookies_arr['MoenyCount'] = 0;
			foreach($Mcartlist as $key => $val){
				$key=intval($key);
				if(isset($shoplist[$key]) && $shoplist[$key]['shenyurenshu'] != 0){
					if(($shoplist[$key]['xsjx_time'] != '0') && $shoplist[$key]['xsjx_time'] < time()){
						unset($shoplist[$key]);
						$shopguoqi = 1;
						continue;
					}
					$shoplist[$key]['cart_gorenci']=$val['num'] ? $val['num'] : 1;
					if($shoplist[$key]['cart_gorenci'] >= $shoplist[$key]['shenyurenshu']){
						$shoplist[$key]['cart_gorenci'] = $shoplist[$key]['shenyurenshu'];
					}
					$MoenyCount+=$shoplist[$key]['yunjiage']*$shoplist[$key]['cart_gorenci'];
					$shoplist[$key]['cart_xiaoji']=substr(sprintf("%.3f",$shoplist[$key]['yunjiage'] * $shoplist[$key]['cart_gorenci']),0,-1);
					$shoplist[$key]['cart_shenyu']=$shoplist[$key]['zongrenshu']-$shoplist[$key]['canyurenshu'];
					$scookies_arr[$key]['shenyu'] = $shoplist[$key]['cart_shenyu'];
					$scookies_arr[$key]['num'] = $shoplist[$key]['cart_gorenci'];
					$scookies_arr[$key]['money'] = intval($shoplist[$key]['yunjiage']);
					$scookies_arr['MoenyCount'] += intval($shoplist[$key]['cart_xiaoji']);
				}else{
					unset($shoplist[$key]);
				}
			}
			if(count($shoplist) < 1){
				$scookies_arr = '0';
				$this->model->rollback();
				if($shopguoqi){
					$this->ajaxReturn(array('status' => 0,'msg' => '限时揭晓过期商品不能购买'));
				}else{
					$this->ajaxReturn(array('status' => 0,'msg' => '购物车里没有商品'));
				}
			}
		}else{
			$scookies_arr = '0';
			$this->model->rollback();
			$this->ajaxReturn(array('status' => 0,'msg' => '购物车里商品已经卖完或已下架'));
		}
	
		if ($this->userinfo['money'] >= $MoenyCount) {
			$this->ajaxReturn(array('status' => 2,'msg' => 'xxxx'));
		}
		$money = $MoenyCount-$this->userinfo['money'];
	
		$config = $this->config();
		$pay_type = $config['extra']['pay_type'];
		unset($config['extra']['pay_type']);
		$this->executePay($config, $money, $pay_type, '购买商品', '购买商品',$scookies_arr,1);
	}
	
	/**
	 * 生成支付通道
	 * @param Array $config
	 * @param int $money
	 * @param String $pay_type
	 * @param String $subject
	 * @param String $body
	 * @param Array|null $scookies
	 * @param int $buy 0不清除cookie,1清除单人夺宝cookie,2清除组团cookie,3清除参团cookie
	 */
	private function executePay($config,$money,$pay_type,$subject,$body,$scookies='',$buy=0){
		$this->model->startTrans();
		//设置 API Key
		Pingpp\Pingpp::setApiKey($config['api_key']);
		try {
			$ch = Pingpp\Charge::create(
					array(
							'subject'   => $subject,
							'body'      => $body,
							'amount'    => $money*100,
							'order_no'  => $config['orderNo'],
							'currency'  => 'cny',
							'extra'     => $config['extra'],
							'channel'   => $config['channel'],
							'client_ip' => $_SERVER['REMOTE_ADDR'],
							'app'       => array('id' => $config['app_id'])
					)
			);
			$arr = json_decode($ch,true);
			$changeid = $arr['id'];
			if (empty($scookies)){
				$scookies = '0';
			}else{
				$scookies = serialize($scookies);
			}
			$dingdancode = 'C'.time().substr(microtime(),2,6).rand(0,9);		//订单号
			//$pay_type = '微信公众号';
			$time = time();
			$score = 0;
			$uid = $this->userinfo['uid'];
			$query = $this->model->execute("INSERT INTO `__PREFIX__member_addmoney_record` (`uid`, `code`, `money`,`changeid`, `pay_type`, `status`,`time`,`score`,`scookies`) VALUES ('$uid', '$dingdancode', '$money','$changeid', '$pay_type','未付款', '$time','$score','$scookies')");
			if($query){
				$this->model->commit();
			}else{
				$this->model->rollback();
				if ($buy == 1){
					_setcookie('Cartlist',NULL);
				}elseif ($buy == 2){
					_setcookie('team_cartlist', null);
				}elseif ($buy == 3){
					_setcookie('go_team_cartlist', null);
				}
				$this->ajaxReturn(array('status' => 0,'msg' => '生成支付订单失败'));
			}
			echo $ch;
		} catch (Pingpp\Error\Base $e) {
			// 捕获报错信息
			if ($e->getHttpStatus() != NULL) {
				header('Status: ' . $e->getHttpStatus());
				echo $e->getHttpBody();
			} else {
				echo $e->getMessage();
			}
		}
	}
	
	//充值
	public function recharge(){
		if (!IS_AJAX) return false;
		if (!$this->userinfo){
			$this->ajaxReturn(array('status' => 0,'msg' => '请登录用户'));
		}
		$config = $this->config();
		$pay_type = $config['extra']['pay_type'];
		unset($config['extra']['pay_type']);
		$money = $config['amount'];
		$this->executePay($config, $money, $pay_type, '账户充值', '账户充值');
	}
	
	public function webhooks(){
		require $this->path.'/init.php';
		$raw_data = file_get_contents('php://input');
		$headers = Util::getRequestHeaders();
		$signature = isset($headers['X-Pingplusplus-Signature']) ? $headers['X-Pingplusplus-Signature'] : NULL;
		$pub_key_path = $this->path . "/pay/pingpp_rsa_public_key.pem";
		$result = $this->verify_signature($raw_data, $signature, $pub_key_path);
		if ($result === 1) {
			// 验证通过
			file_put_contents('sign_status.txt', $raw_data);
		} elseif ($result === 0) {
			http_response_code(400);
			echo 'verification failed';
			exit;
		} else {
			http_response_code(400);
			echo 'verification error';
			exit;
		}
	
		$event = json_decode($raw_data, true);
		if ($event['type'] == 'charge.succeeded') {
			$charge = $event['data']['object'];
			$out_trade_no = $charge['id'];
			$dingdaninfo = $this->model->query("select * from `__PREFIX__member_addmoney_record` where `changeid` = '$out_trade_no'");
			if(!$dingdaninfo){
				http_response_code(400);
				echo 'verification failed';
				exit;
			}
			$dingdaninfo = current($dingdaninfo);
			if ($dingdaninfo['status'] == '已付款' ) {
				http_response_code(200);
				exit;
			}
			$total_fee_t = $charge['amount']/100;
			$this->model->startTrans();
			$dingdaninfo = $this->model->query("select * from `__PREFIX__member_addmoney_record` where `changeid` = '$out_trade_no' and `money` = '$total_fee_t' and `status` = '未付款' for update");
			if(!$dingdaninfo){
				http_response_code(400);
				echo 'verification failed';
				exit;
			}
			$dingdaninfo = current($dingdaninfo);
			$uid = $dingdaninfo['uid'];
			$pay_type = '通过'.$dingdaninfo['pay_type'].'充值';
			$time = time();
			$up_q1 = $this->model->execute("UPDATE `__PREFIX__member_addmoney_record` SET `status` = '已付款' where `id` = '$dingdaninfo[id]' and `code` = '$dingdaninfo[code]'");
			$up_q2 = $this->model->execute("UPDATE `__PREFIX__users` SET `userMoney` = `userMoney` + $total_fee_t where (`userId` = '$dingdaninfo[uid]')");
			$up_q3 = $this->model->execute("INSERT INTO `__PREFIX__member_account` (`uid`, `type`, `pay`, `content`, `money`, `time`) VALUES ('$dingdaninfo[uid]', '1', '账户', '$pay_type', '$total_fee_t', '$time')");
			if($up_q1 && $up_q2 && $up_q3){
				$this->model->commit();
				$this->model->execute("UPDATE `__PREFIX__member_addmoney_record` SET `scookies` = '1' where `changeid` = '$out_trade_no' and `status` = '已付款'");
				http_response_code(200);
			}else{
				$this->model->rollback();
				http_response_code(400);
				echo 'verification failed';
				exit;
			}
				
		} elseif ($event['type'] == 'refund.succeeded') {
			$refund = $event['data']['object'];
			// ...
			http_response_code(200); // PHP 5.4 or greater
		} else {
			/**
			 * 其它类型 ...
			 * - summary.daily.available
			 * - summary.weekly.available
			 * - summary.monthly.available
			 * - transfer.succeeded
			 * - red_envelope.sent
			 * - red_envelope.received
			 * ...
			 */
			http_response_code(200);
	
			// 异常时返回非 2xx 的返回码
			// http_response_code(400);
		}
	}
	
	// 验证 webhooks 签名方法
	private function verify_signature($raw_data, $signature, $pub_key_path) {
		$pub_key_contents = file_get_contents($pub_key_path);
		// php 5.4.8 以上，第四个参数可用常量 OPENSSL_ALGO_SHA256
		return openssl_verify($raw_data, base64_decode($signature), $pub_key_contents, 'sha256');
	}
	
	
}